package com.filetransfer.filemanager.util;

import java.io.File;
import java.io.RandomAccessFile;
import java.util.List;

import com.filetransfer.domain.FileInfo;
import com.filetransfer.domain.FileInfoHolder;

public class FileUtil {


	public static final int maxChnkSize = 4*1024*1024;

	public static final int minChnkSize = 5*1024;

	public static final int stdNumOfChnks = 20;



	public static void main(String[] a){
		File file = new File("C:\\temp\\custom.properties.bak");
		RandomAccessFile randFile = null;


		try{
//			randFile = new RandomAccessFile(file,"r");
//
//			int chunkSizeInBytes = 5*1024; //5KB
//			byte[] temp = new byte[chunkSizeInBytes];
//			long filePtr = 10240;
////			filePtr = randFile.getFilePointer();
//			randFile.seek(filePtr);
//
//
//			randFile.readFully(temp);
//			String str = new String(temp);
//			filePtr = randFile.getFilePointer();


			System.out.println(Integer.MAX_VALUE);



		}catch(Exception e){
			e.printStackTrace();
		}
	}


	/**
	 *
	 * @param holder
	 */
	public static void listFilesOnFileServer(FileInfoHolder holder){
		System.out.println("-- Files Available for Download --:");
		listFiles(holder.getFileInfoList(true));
	}

	
	public static void listFilesOnDownloader(FileInfoHolder holder){
		System.out.println("-- Files Fully Downloaded --:");
		listFiles(holder.getFileInfoList(true));
	}

	/**
	 * Invoked by both the FileManager and the FileDownloader
	 * @param list
	 */
	public static void listFiles(List<FileInfo> list){
		if(list != null && list.size() > 0){
			System.out.println("Name                           Size(KB)");
			System.out.println("=======================================");
			for(FileInfo info:list){
				System.out.println(info.getFileName() + "                 " + info.getFileSize()/1024);
			}
		}else{
			System.out.println("No files available!");
		}
		System.out.println("-----------------");
	}

	/**
	 * LOGIC :
	 *
		0. if(fileSize < minChnkSize) then set chnkSize = fileSize; skip the rest of steps.

		1. chnkSize = fileSize/stdNumOfChnks

		2. if (chnkSize > maxChnkSize) then { chnkSize = maxChnkSize; numOfChnks = fileSize / chnkSize; }

		   else if (chnkSize < minChnkSize) then {chnkSize = minChnkSize; numOfChnks = fileSize/chnkSize; }

		   else // i.e., the chnkSize is between 5KB and 4MB, so we just go with the numOfChunks as 20 //
		          { numOfChnks = stdNumOfChnks; }

		3. return back the chnkSize and numOfChnks

	 *
	 *  Problems with using int as the chnkSize will only
	 *  come when we can consider a chunk of size greater than 2GB.
	 *  Integer.MAX_INT value is 2GB, so we are safe.
	 *
	 * @param obj
	 * @return
	 */
	public static FileInfo calculateChunkDetails(FileInfo obj){
		int chnkSize =0, numChunks=0;
		long fileSize = 0;



		if(obj != null && obj.getFileSize() > 0){
			fileSize = obj.getFileSize();

			if(fileSize < minChnkSize){
				chnkSize = (int)fileSize;
				numChunks = 1;
			}else{
				chnkSize = (int) (fileSize/stdNumOfChnks);

				if(chnkSize > maxChnkSize){
					chnkSize = maxChnkSize;
					numChunks = (int)(fileSize/chnkSize);
				}else if(chnkSize < minChnkSize){
					chnkSize = minChnkSize;
					numChunks = (int)(fileSize/chnkSize);
				}else{
					numChunks = stdNumOfChnks;
				}

				/*
				 * In case if the file has a smaller portion remaining after diving by the chunk size, then
				 *  taht portion is the last chunk, and it will be smaller than the resto f the chunks.
				 *  that needs to be added to the final number of chunks.
				 */
				if(fileSize % chnkSize > 0){
					numChunks++;
				}

			}
		}

		obj.setChunkSize(chnkSize);
		obj.setNumChunks(numChunks);

		return obj;
	}



}
